package com.one.blocks.rbac.valid.validator;

import com.one.blocks.mvc.util.ScopeWebRequestHelper;
import com.one.blocks.rbac.controller.vo.SysMenuVo;
import com.one.blocks.rbac.domain.SysMenu;
import com.one.blocks.rbac.enums.MenuTypeEnum;
import com.one.blocks.rbac.manager.SysMenuManager;
import com.one.blocks.rbac.valid.constraints.HierarchyMenuType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import static com.one.blocks.rbac.constant.RbacConstant.ScopeRequest.VALID_MENU_ID;

/**
 * @author linfuxin Created on 2022-08-16 17:41:36
 */
@Slf4j
public class HierarchyMenuTypeValidator implements ConstraintValidator<HierarchyMenuType, SysMenuVo> {

    @Autowired
    private SysMenuManager sysMenuManager;

    @Override
    public boolean isValid(SysMenuVo value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        // 上下级类型是否正确
        return !hasErrorType(ScopeWebRequestHelper.get(VALID_MENU_ID + value.getParentId(), () -> sysMenuManager.get(value.getParentId())), value, context);
    }

    private boolean hasErrorType(SysMenu parentMenu, SysMenuVo value, ConstraintValidatorContext context) {
        if (parentMenu == null) {
            // 正常类型
            if (MenuTypeEnum.BUTTON.match(value.getType())) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate("按钮节点父节点不能为null").addConstraintViolation();
                return true;
            }
            return false;
        }

        // 父目录 folder => 子目录 folder || menu
        if (MenuTypeEnum.FOLDER.match(parentMenu.getType())) {
            if (!MenuTypeEnum.FOLDER.match(value.getType()) && !MenuTypeEnum.MENU.match(value.getType())) {
                context.disableDefaultConstraintViolation();
                context.buildConstraintViolationWithTemplate("父节点为目录,子节点只能为目录或菜单").addConstraintViolation();
                return true;
            }
        }

        // 父目录 menu => 子目录 button
        if (MenuTypeEnum.MENU.match(parentMenu.getType())) {
            if (MenuTypeEnum.BUTTON.match(value.getType())) {
                return false;
            }
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("父节点为菜单,子节点只能为按钮").addConstraintViolation();
            return true;
        }

        // 未知类型
        return true;
    }
}
